package com.sc.nft.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.sc.nft.dao.MallActivityShareDao;
import com.sc.nft.dao.MallGoodsLabelDao;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.*;
import com.sc.nft.entity.vo.*;
import com.sc.nft.entity.vo.mall.MallProductLabelVO;
import com.sc.nft.enums.MallGoodsLabelEnums;
import com.sc.nft.enums.ShareTeamStatusEnum;
import com.sc.nft.enums.task.ParticipantsEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.*;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.util.BigDecimalUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 分享购活动 服务实现类
 * </p>
 *
 * @author ligen
 * @since 2023-12-11
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class MallActivityShareServiceImpl implements MallActivityShareService {

    private final MallActivityShareDao mallActivityShareDao;
    private final MallActivitySpecsService mallActivitySpecsService;
    private final MallActivityShareSpecsService mallActivityShareSpecsService;
    private final MallProfitTemplateService mallProfitTemplateService;
    @Autowired
    MallActivityShareTeamService mallActivityShareTeamService;
    @Autowired
    MallActivityService mallActivityService;
    private final MallGoodsLabelDao mallGoodsLabelDao;

    /**
     * 创建分享购活动
     *
     * @param vo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(EditMallActivityShareVO vo) {
        // 校验
        check(vo);
        MallActivityShare mallActivityShare = new MallActivityShare();
        mallActivityShare.setActivityId(vo.getActivityId());
        mallActivityShare.setValidMinute(vo.getValidMinute());
        mallActivityShare.setMinOrderNum(vo.getMinOrderNum());
        mallActivityShare.setRewardPercentage(vo.getRewardPercentage());
        mallActivityShare.setDetailedRules(vo.getDetailedRules());
        mallActivityShare.setCollectionId(vo.getCollectionId());
        mallActivityShare.setStatus(false);
        mallActivityShare.insert();
        mallActivityShareSpecsService.createList(vo.getMallActivityShareSpecsVOList(), mallActivityShare.getId(), vo.getActivityId());
    }

    /**
     * 获取成团的分享购活动
     *
     * @param teamId
     * @return
     */
    @Override
    public MallActivityShare getByTeamId(Long teamId) {
        MallActivityShareTeam mallActivityShareTeam = mallActivityShareTeamService.getById(teamId);
        return getById(mallActivityShareTeam.getActivityShareId());
    }

    /**
     * 校验
     *
     * @param vo
     */
    private void check(EditMallActivityShareVO vo) {
        MallActivity mallActivity = mallActivityService.getById(vo.getActivityId());
        Assert.notNull(mallActivity, () -> new GlobalRunTimeException("活动不存在"));
        Assert.isTrue(vo.getParticipants() == ParticipantsEnum.UNLIMITED || vo.getCollectionId() != null, "请指定可开团人需要持有的NFT");
        Integer maxValidMinute = 29 * 24 * 60 + 23 * 60 + 59;
        Integer minValidMinute = 15;
        if (vo.getValidMinute() > maxValidMinute || vo.getValidMinute() < minValidMinute) {
            throw new GlobalRunTimeException("超出拼团有效期范围");
        }
        if (vo.getMinOrderNum() <= 0) {
            throw new GlobalRunTimeException("最低单数必须大于等于1");
        }
        if (BigDecimalUtils.compare(0.01, vo.getRewardPercentage())) {
            throw new GlobalRunTimeException("奖励比例需大于0.01");
        }
        if (BigDecimalUtils.compare(vo.getRewardPercentage(), 1)) {
            throw new GlobalRunTimeException("奖励比例需小于1");
        }
        // 分享购活动规格
        List<EditMallActivityShareSpecsVO> mallActivityShareSpecsVOList = vo.getMallActivityShareSpecsVOList();
        for (EditMallActivityShareSpecsVO editMallActivityShareSpecsVO : mallActivityShareSpecsVOList) {
            // 判断拼团价格
            MallActivitySpecs mallActivitySpecs = mallActivitySpecsService.getById(editMallActivityShareSpecsVO.getActivitySpecsId());
            if (BigDecimalUtils.compare(BigDecimalUtils.add(mallActivitySpecs.getCostPrice(), mallActivitySpecs.getActivityCostPrice(), mallActivitySpecs.getReservePrice()), editMallActivityShareSpecsVO.getShareSalesPrice())) {
                throw new GlobalRunTimeException("拼团价不得小于成本价");
            }
            if (BigDecimalUtils.compare(editMallActivityShareSpecsVO.getShareSalesPrice(), mallActivitySpecs.getSalesPrice())) {
                throw new GlobalRunTimeException("拼团价不得大于销售价");
            }
        }
    }

    @Override
    public MallActivityShare getById(Long id) {
        MallActivityShare mallActivityShare = mallActivityShareDao.getById(id);
        Assert.notNull(mallActivityShare, () -> new GlobalRunTimeException(ErrorCode.SHARE_BUYING_ACTIVITY_DOES_NOT_EXIST));
        return mallActivityShare;
    }

    /**
     * 判断活动商品是否拥有拼团活动
     *
     * @param activityId
     * @return
     */
    @Override
    public Boolean hasShareByActivityId(Long activityId) {
        return mallActivityShareDao.hasShareByActivityId(activityId);
    }


    /**
     * 分享购活动列表
     *
     * @param adminMallActivitySharePageVO
     * @return
     */
    @Override
    public Page<AdminMallActivitySharePageDTO> getAdminMallActivitySharePageDTO(AdminMallActivitySharePageVO adminMallActivitySharePageVO) {
        Page<AdminMallActivitySharePageDTO> adminMallActivitySharePageDTO = mallActivityShareDao.getAdminMallActivitySharePageDTO(adminMallActivitySharePageVO.getPageNo(), adminMallActivitySharePageVO.getPageSize(), adminMallActivitySharePageVO.getProductName(), adminMallActivitySharePageVO.getDaoId(), adminMallActivitySharePageVO.getStatus());
        for (AdminMallActivitySharePageDTO record : adminMallActivitySharePageDTO.getRecords()) {
            if (StrUtil.isNotBlank(record.getCoverImage())) {
                record.setCoverImage(StrUtil.split(record.getCoverImage(), ",").get(0));
            }
        }
        return adminMallActivitySharePageDTO;
    }

    /**
     * 用户端分享购活动列表
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public Page<MallActivitySharePageDTO> getMallActivitySharePageDTO(Long userId, Integer pageNo, Integer pageSize) {
        Page<MallActivitySharePageDTO> mallActivitySharePageDTO = mallActivityShareDao.getMallActivitySharePageDTO(pageNo, pageSize);
        for (MallActivitySharePageDTO record : mallActivitySharePageDTO.getRecords()) {
            MallActivityShareTeam mallActivityShareTeam = mallActivityShareTeamService.hasShareTeamDetail(userId, record.getId());
            if (Objects.nonNull(mallActivityShareTeam)) {
                record.setIsStartGroup(Boolean.TRUE);
                record.setTeamId(mallActivityShareTeam.getId());
            } else {
                record.setIsStartGroup(Boolean.FALSE);
            }
            if (StrUtil.isNotBlank(record.getCoverImage())) {
                record.setCoverImage(StrUtil.split(record.getCoverImage(), ",").get(0));
            }
            //判断标签
            if (record.getLabelType() != null) {
                if (record.getLabelType() == MallGoodsLabelEnums.NEW_LABEL) {
                    //新品，判断商品的创建时间是否大于标签的创建时间
                    if (record.getLabelStartTime().after(record.getCreateTime()) || !DateUtil.isIn(new Date(),record.getLabelStartTime(),record.getLabelEndTime())) {
                        record.setLabelImage(null);
                    }
                }else if (record.getLabelType() == MallGoodsLabelEnums.ACTIVITY_LABEL) {
                    //活动
                    if (!DateUtil.isIn(new Date(),record.getLabelStartTime(),record.getLabelEndTime())) {
                        record.setLabelImage(null);
                    }
                }
            }
        }
        return mallActivitySharePageDTO;
    }

    /**
     * 分享购活动详情
     *
     * @param id
     * @return
     */
    @Override
    public MallActivityShareDetailDTO getMallActivityShareDetailDTO(Long id) {
        MallActivityShareDetailDTO mallActivityShareDetailDTO = mallActivityShareDao.getAdminMallActivityShareDetailDTO(id);
        Assert.notNull(mallActivityShareDetailDTO, () -> new GlobalRunTimeException("分享活动不存在"));
        List<AdminMallActivityShareSpecsDetailDTO> adminMallActivityShareSpecsDetailDTOList = mallActivityShareSpecsService.getAdminShareSpecsDetailDTOListByShareId(mallActivityShareDetailDTO.getId());
        mallActivityShareDetailDTO.setAdminMallActivityShareSpecsDetailDTOList(adminMallActivityShareSpecsDetailDTOList);
        //查询商品绑定的标签
        List<MallGoodsLabel> mallGoodsLabelList = mallGoodsLabelDao.productDetailsGetLabel(mallActivityShareDetailDTO.getActivityId());
        if (!CollectionUtils.isEmpty(mallGoodsLabelList)){
            List<MallProductLabelVO> labelList = new ArrayList<>();
            for (MallGoodsLabel mallGoodsLabel : mallGoodsLabelList) {
                if (mallGoodsLabel.getLabelType() != null) {
                    if (mallGoodsLabel.getLabelType() == MallGoodsLabelEnums.NEW_LABEL) {
                        //新品，判断商品的创建时间是否大于标签的创建时间
                        if (mallGoodsLabel.getStartTime().before(mallActivityShareDetailDTO.getCreateTime()) && DateUtil.isIn(new Date(), mallGoodsLabel.getStartTime(), mallGoodsLabel.getEndTime())) {
                            MallProductLabelVO mallProductLabelVO = new MallProductLabelVO();
                            mallProductLabelVO.setLabelType(mallGoodsLabel.getLabelType());
                            mallProductLabelVO.setLabelImage(mallGoodsLabel.getLabelImage());
                            labelList.add(mallProductLabelVO);
                        }
                    } else if (mallGoodsLabel.getLabelType() == MallGoodsLabelEnums.ACTIVITY_LABEL) {
                        //活动
                        if (DateUtil.isIn(new Date(), mallGoodsLabel.getStartTime(), mallGoodsLabel.getEndTime())) {
                            MallProductLabelVO mallProductLabelVO = new MallProductLabelVO();
                            mallProductLabelVO.setLabelType(mallGoodsLabel.getLabelType());
                            mallProductLabelVO.setLabelImage(mallGoodsLabel.getLabelImage());
                            labelList.add(mallProductLabelVO);
                        }
                    }
                }
            }
            mallActivityShareDetailDTO.setLabelList(labelList);
        }
        return mallActivityShareDetailDTO;
    }

    /**
     * 分享购活动上架
     *
     * @param id
     */
    @Override
    public void enable(Long id) {
        MallActivityShare mallActivityShare = getById(id);
        MallActivity mallActivity = mallActivityService.getById(mallActivityShare.getActivityId());
        if (!mallActivity.getStatus()) {
            throw new GlobalRunTimeException("活动商品未上架");
        }
        mallActivityShareDao.updateStatus(mallActivityShare.getId(), true);
    }

    /**
     * 分享购活动下架
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disable(Long id) {
        MallActivityShare mallActivityShare = getById(id);
        mallActivityShareDao.updateStatus(mallActivityShare.getId(), false);
        // 所有已经开团的都算开团成功 但是当订单退款变成订单结束时重新计算是否满足最低数量
        updateTeamStatus(id);
    }

    /**
     * 活动下架成团自动成功
     *
     * @param activityShareId
     */
    private void updateTeamStatus(Long activityShareId) {
        List<MallActivityShareTeam> mallActivityShareTeams = mallActivityShareTeamService.getListByActivityShareId(activityShareId, ShareTeamStatusEnum.GROUPING_IN_PROGRESS);
        for (MallActivityShareTeam mallActivityShareTeam : mallActivityShareTeams) {
            mallActivityShareTeamService.updateIsCanIssue(mallActivityShareTeam.getId(), Boolean.TRUE, Boolean.TRUE);
        }
    }

    /**
     * 分享购活动下架
     *
     * @param activityId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disableByActivityId(Long activityId) {
        List<MallActivityShare> mallActivityShareList = getListByActivityId(activityId);
        for (MallActivityShare mallActivityShare : mallActivityShareList) {
            disable(mallActivityShare.getId());
        }
    }

    /**
     * 获取营销活动的已经上架分享购
     *
     * @param activityId
     * @return
     */
    @Override
    public List<MallActivityShare> getListByActivityId(Long activityId) {
        return mallActivityShareDao.getListByActivityId(activityId);
    }

    /**
     * 修改分享购活动排序
     *
     * @param id
     * @param sort
     */
    @Override
    public void updateSort(Long id, Integer sort) {
        MallActivityShare mallActivityShare = getById(id);
        mallActivityShareDao.updateSort(mallActivityShare.getId(), sort);
    }

    /**
     * 获取分享购团长可得最大收益
     *
     * @param maxRewardPercentageVO
     * @return
     */
    @Override
    public BigDecimal maxRewardPercentage(MaxRewardPercentageVO maxRewardPercentageVO) {
        List<BigDecimal> maxRewardPercentageList = Lists.newArrayList();
        Boolean isZero = false;
        // 活动商品规格
        List<MallActivitySpecs> mallActivitySpecsList = mallActivitySpecsService.getByActivityId(maxRewardPercentageVO.getActivityId());
        Map<Long, BigDecimal> shareSalesPriceMap = maxRewardPercentageVO.getMallActivityShareSpecsVOList().stream().collect(Collectors.toMap(EditMallActivityShareSpecsVO::getActivitySpecsId, EditMallActivityShareSpecsVO::getShareSalesPrice));
        for (MallActivitySpecs mallActivitySpecs : mallActivitySpecsList) {
            if (Objects.nonNull(mallActivitySpecs.getProfitTemplateId())) {
                MallProfitTemplate mallProfitTemplate = mallProfitTemplateService.getById(mallActivitySpecs.getProfitTemplateId());
                if (Objects.nonNull(mallProfitTemplate)) {
                    BigDecimal salesPrice = shareSalesPriceMap.get(mallActivitySpecs.getId());
                    if (Objects.isNull(salesPrice)) {
                        salesPrice = mallActivitySpecs.getSalesPrice();
                    }
                    BigDecimal profit = BigDecimalUtils.subtract(salesPrice, mallActivitySpecs.getCostPrice(), mallActivitySpecs.getActivityCostPrice(), mallActivitySpecs.getReservePrice());
                    BigDecimal multiplys = BigDecimalUtils.multiplys(profit, mallProfitTemplate.getMallIncome());
                    BigDecimal divide = BigDecimalUtils.divide(multiplys, mallActivitySpecs.getSalesPrice());
                    maxRewardPercentageList.add(divide);
                } else {
                    isZero = true;
                }
            } else {
                isZero = true;
            }
        }
        BigDecimal maxRewardPercentage = BigDecimal.ZERO;
        if (!isZero) {
            maxRewardPercentage = maxRewardPercentageList.stream().min(Comparator.comparing(x -> x)).orElse(BigDecimal.ZERO);
        }
        return maxRewardPercentage;
    }
}
